#include "worker.h"
#include <QDebug>
#include <QThread>
#include <QFileInfo>
worker::worker( QMutex *mutex,QObject *parent)
    : QObject(parent),m_mutex(mutex),m_serialPort(nullptr),m_fileSendTimer(nullptr),m_totalFileSize(0),m_bytesSent(0){

    m_serialPort = new QSerialPort(this);
    connect(m_serialPort,&QSerialPort::errorOccurred,this,[=](QSerialPort::SerialPortError error){
        if(error!=QSerialPort::NoError){
            switch (error) {
            case QSerialPort::DeviceNotFoundError:
                emit errorOccurred("串口线断开");
                break;
            case QSerialPort::PermissionError:
                emit errorOccurred("串口打开失败!\n"
                                   "请检查指定串口是否存在或者已被打开");
                break;
            case QSerialPort::OpenError:
                emit errorOccurred("打开设备时出错");
                break;
            case QSerialPort::ResourceError:
                emit errorOccurred("设备被意外移除或者串口被占用");
                break;
            case QSerialPort::NotOpenError:
                emit errorOccurred("串口未打开");
                break;
            default:
                emit errorOccurred("其他错误");
                break;
            }
        }
    });
}
worker::~worker()
{
    if (m_fileSendTimer && m_fileSendTimer->isActive()) {
        m_fileSendTimer->stop();
    }
    if (m_serialPort && m_serialPort->isOpen()) {
        m_serialPort->close();
    }
}

bool worker::isPortOpen() const {
    return m_serialPort && m_serialPort->isOpen();
}

void worker::openPort(const QString &portName,int baudRate,int dataBits,int stopBits,int parity)
{
    QMutexLocker locker(m_mutex);
    if(m_serialPort->isOpen())
    {
        emit portOpened(false,"串口已打开");
        return;
    }
    // 初始化串口属性，设置 端口号、波特率、数据位、停止位、奇偶校验位数
    m_serialPort->setPortName(portName);
    m_serialPort->setBaudRate(baudRate);
    m_serialPort->setDataBits(static_cast<QSerialPort::DataBits>(dataBits));
    m_serialPort->setStopBits(static_cast<QSerialPort::StopBits>(stopBits));
    m_serialPort->setParity(static_cast<QSerialPort::Parity>(parity));

    if(m_serialPort->open(QIODevice::ReadWrite))
    {
        connect(m_serialPort,&QSerialPort::readyRead,this,&worker::recvData);
        emit portOpened(true,QString("%1 已打开").arg(portName));
    }else
    {
        emit portOpened(false,m_serialPort->errorString());
    }
}

void worker::recvData()
{
    QMutexLocker locker(m_mutex);
    QByteArray buffer = m_serialPort->readAll();
    if(!buffer.isEmpty())
    {
        qDebug()<<"先检查缓存区可用字节数"<<m_serialPort->bytesAvailable();
        qDebug() << "接收数据线程ID：" << QThread::currentThreadId();
        qDebug() << "接收到的数据：" << buffer; // 添加调试信息
        emit sendResultTO(buffer);//之前是str_rev
    }
}

void worker::sendData(const QByteArray &data)
{
    QMutexLocker locker(m_mutex);
    if ( !m_serialPort->isOpen() && !m_serialPort) {
        //qDebug() << "串口未打开，无法发送！";
        emit errorOccurred("串口未打开");
        return;
    }
    if(m_serialPort&& m_serialPort->isOpen())
    {
        int bytesWritten = m_serialPort->write(data);
        if(bytesWritten == -1)
        {
            emit errorOccurred("发送失败： " + m_serialPort->errorString());
        }
        else if(bytesWritten < data.size()){
            emit errorOccurred("发送不完整");
        }
        else{
            emit sendBytesWritten(bytesWritten);
            m_serialPort->waitForBytesWritten(100);
        }
    }
    else
    {
        emit errorOccurred("未打开串口");
        qDebug() <<  "打开串口失败 ";
    }
}

void worker::closePort()
{
    if(m_serialPort->isOpen())
    {
        m_serialPort->close();
        emit portOpened(false,"串口已关闭");
    }
}

void worker::sendFile(const QString &filePath, int frameLen, int frameGap)
{
    QMutexLocker locker(m_mutex);

    //检查串口状态
    if(!m_serialPort->isOpen()||!m_serialPort) {
        emit errorOccurred("串口未打开");
        return;
    }
    //检查文件路径
    QFileInfo fileInfo(filePath);
    if(!fileInfo.exists())
    {
        emit errorOccurred("文件不存在");
        return;
    }
    //打开文件
    m_currentFile.setFileName(filePath);
    if(!m_currentFile.open(QIODevice::ReadOnly)){
        QString error = QString("无法打开文件: %1 (错误代码: %2)")
                            .arg(m_currentFile.errorString())
                            .arg(m_currentFile.error());
        emit errorOccurred(error);
        return;
    }
    //检查文件大小
    m_totalFileSize = m_currentFile.size();
    if(m_totalFileSize == 0)
    {
        m_currentFile.close();
        emit errorOccurred("文件为空");
        return;
    }

    m_bytesSent = 0;
    m_frameLen = frameLen;
    m_frameGap = frameGap;

    if(frameLen == 0 || frameGap == 0)
    {
        QByteArray fileData = m_currentFile.readAll();
        m_currentFile.close();

        if(fileData.isEmpty())
        {
            emit errorOccurred("文件读取失败");
            return;
        }

        qint64 bytesWritten = m_serialPort->write(fileData);
        if(bytesWritten == -1)
        {
            emit errorOccurred("发送失败： "+m_serialPort->errorString());
        }else{
            emit sendBytesWritten(bytesWritten);
            emit fileProgress(100);
            emit fileTransferFinished();
        }
        return;
    }
    //正常分帧发送
    if(!m_fileSendTimer) {
        m_fileSendTimer = new QTimer(this);
        connect(m_fileSendTimer, &QTimer::timeout, this, &worker::sendNextFileFrame);
    }

    m_fileSendTimer->start(m_frameGap);
    qDebug() << "文件发送开始，总大小:" << m_totalFileSize << "字节";
}

void worker::sendNextFileFrame()
{
    QMutexLocker locker(m_mutex);

    if(!m_currentFile.isOpen()){
        if(m_fileSendTimer)
            m_fileSendTimer->stop();
        emit errorOccurred("文件未打开");
        return;
    }

    if(m_bytesSent >= m_totalFileSize) {
        m_fileSendTimer->stop();
        m_currentFile.close();
        emit fileTransferFinished();
        emit fileProgress(100);
        return;
    }

    QByteArray frame = m_currentFile.read(m_frameLen);
    if(frame.isEmpty() && !m_currentFile.atEnd())
    {
        qDebug() << "文件读取失败，可能文件已到达末尾或读取错误。"<<m_currentFile.errorString();
        m_fileSendTimer->stop();
        m_currentFile.close();
        emit errorOccurred("文件读取失败: "+m_currentFile.errorString());
        return;
    }

    qint64 bytesWritten = m_serialPort->write(frame);
    qDebug() << "尝试写入的字节数: " << frame.size() << ", 实际写入的字节数: " << bytesWritten;
    if(bytesWritten == -1) {
        m_fileSendTimer->stop();
        m_currentFile.close();
        emit errorOccurred("文件发送失败: " + m_serialPort->errorString());
        return;
    }

    m_bytesSent += bytesWritten;
    emit sendBytesWritten(bytesWritten);

    int progress = 0;
    if(m_totalFileSize > 0) {
        progress = qMin(100,
                        static_cast<int>((m_bytesSent * 100) / m_totalFileSize));
    }
    emit fileProgress(progress);
    // int progress = static_cast<int>((m_bytesSent * 100) / m_totalFileSize);
    // emit fileProgress(progress > 100 ? 100 : progress);
    qDebug() << "已发送字节数: " << m_bytesSent << ", 总字节数: " << m_totalFileSize; // 添加调试信息
}

void worker::cancelFileTransfer()
{
    QMutexLocker locker(m_mutex);

    if(m_fileSendTimer && m_fileSendTimer->isActive()) {
        m_fileSendTimer->stop();
    }

    if(m_currentFile.isOpen()) {
        m_currentFile.close();
    }

    emit fileTransferFinished();
}
